﻿using mozhi.smarterp.Finance.Accounts.Repository;
using mozhi.smarterp.Finance.Basedatas.Events;
using mozhi.smarterp.Finance.Basedatas.Repository;
using mozhi.smarterp.Finance.Querys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.EventBus.Distributed;

namespace mozhi.smarterp.Finance.Accounts
{
    public class AccountDimensionAppService : FinanceAppService, IAccountDimensionAppService
    {
        private IAccountDimensionRepository _repository;
        private AccountDimensionManager _manager;
        private ITagRepository _tagRepository;
        private IDistributedEventBus _distributedEventBus;
        public AccountDimensionAppService(IAccountDimensionRepository repository, AccountDimensionManager manager , ITagRepository tagRepository , 
            IDistributedEventBus distributedEventBus)
        {
            this._repository = repository;
            this._manager = manager;
            this._tagRepository = tagRepository;
            _distributedEventBus = distributedEventBus;
        }

        public async Task<AccountDimensionDto> GetAsync(Guid id)
        {
            var dimension = await _repository.GetAsync(id);

            return ObjectMapper.Map<AccountDimension, AccountDimensionDto>(dimension);
        }

        public async Task<PagedResultDto<AccountDimensionDto>> FindAsync(PageQuery query)
        {
            var dimensions = await _repository.FindAsync(query);

            var count = await _repository.GetCountAsync(query);

            var result = new PagedResultDto<AccountDimensionDto>();

            result.TotalCount = count;
            result.Items = ObjectMapper.Map<List<AccountDimension>, List<AccountDimensionDto>>(dimensions);

            if (result.TotalCount == 0)
                return result;

            var tagIds = result.Items.Where(x => x.TagId.HasValue).Select(x => x.TagId.Value).Distinct().ToList();

            if(tagIds.Count==0)
                return result;

            var tags = await _tagRepository.FindAsync(new PageQuery() { Ids = tagIds , PageIndex=1 , PageSize = int.MaxValue });

            foreach (var item in result.Items)
            {
                item.TagName = tags.FirstOrDefault(x => x.Id == item.TagId)?.Name;
            }

            return result;
        }

        public async Task<AccountDimensionDto> CreateAsync(AccountDimensionCreateDto dto)
        {
            var dimension = await _manager.Instance(dto.Code, dto.Name, dto.DataSourceType);

            dimension.ChangeType(dto.DataSourceType, dto.TagId);

            dimension = await _repository.InsertAsync(dimension);

            return ObjectMapper.Map<AccountDimension, AccountDimensionDto>(dimension);
        }



        public async Task<AccountDimensionDto> UpdateAsync(AccountDimensionUpdateDto dto)
        {
            var dimension = await _repository.FindAsync(dto.Id);

            if (dimension == null)
                throw new UserFriendlyException("数据不存在", "100000");

            await _manager.ValidateDuplicate(dto.Code, dto.Name , dto.Id);


            dimension.Change(dto.Code , dto.Name);
            dimension.ChangeType(dto.DataSourceType, dto.TagId);

            await _repository.UpdateAsync(dimension);

            return ObjectMapper.Map<AccountDimension, AccountDimensionDto>(dimension);
        }

        public async Task<bool> DeleteAsync(Guid id)
        {
            var dimension = await _repository.FindAsync(id);

            if (dimension == null)
                throw new UserFriendlyException("数据不存在", "100000");

            await _repository.DeleteAsync(id);

            if (dimension.TagId.HasValue)
                await _distributedEventBus.PublishAsync(new DataAssociationRemoveEvent(id, dimension.TagId.Value));

            return true;
        }

        public async Task<bool> ChangeStatus(ActivateDtoBase request)
        {
            var dimension = await _repository.FindAsync(request.Id);

            if (dimension == null)
                throw new UserFriendlyException("数据不存在", "100000");

            dimension.ChangeStatus(request.Activated);

            await _repository.UpdateAsync(dimension);

            return true;
        }

        #region
        #endregion
    }
}
